home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / interp / tclStruct1.2.tar.gz / tclStruct1.2.tar / tclStruct1.2 / stTrNum.c < prev    next >
C/C++ Source or Header  |  1995-10-17  |  6KB  |  247 lines

  1. /*
  2.  *    tclStruct package
  3.  *  Support 'C' structures in Tcl
  4.  *
  5.  *  Written by Matthew Costello
  6.  *  (c) 1995 AT&T Global Information Solutions, Dayton Ohio USA
  7.  *
  8.  *  See the file "license.terms" for information on usage and
  9.  *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  */
  11. #include "stInternal.h"
  12. STRUCT_SCCSID("@(#)tclStruct:stTrNum.c    1.2    95/10/17")
  13.  
  14.  
  15.  
  16. int
  17. Struct_GetBinaryInt( ptr, length, flags )
  18.   void *ptr;
  19.   int length;
  20.   int flags;
  21. {
  22.     int v;
  23.     unsigned char *p = ptr;
  24.  
  25.     if (flags & STRUCT_FLAG_BIG_ENDIAN) {
  26.     v = ( !(flags & STRUCT_FLAG_UNSIGNED) &&
  27.           (*p & (1<<(CHAR_BIT-1))) ) ? ~0 : 0;
  28.     while (--length >= 0)
  29.         v = (v << CHAR_BIT) | *p++;
  30.     } else {
  31.     p += length - 1;
  32.     v = ( !(flags & STRUCT_FLAG_UNSIGNED) &&
  33.           (*p & (1<<(CHAR_BIT-1))) ) ? ~0 : 0;
  34.     while (--length >= 0)
  35.         v = (v << CHAR_BIT) | *p--;
  36.     }
  37.     return v;
  38. }
  39.  
  40. void
  41. Struct_PutBinaryInt( v, ptr, length, flags )
  42.   int v;
  43.   void *ptr;
  44.   int length;
  45.   int flags;
  46. {
  47.     unsigned char *p = ptr;
  48.  
  49.     if (flags & STRUCT_FLAG_BIG_ENDIAN) {
  50.     p += length;
  51.     while (--length >= 0) {
  52.         *--p = (unsigned char) v;
  53.         v >>= CHAR_BIT;
  54.     }
  55.     } else {
  56.     while (--length >= 0) {
  57.         *p++ = (unsigned char) v;
  58.         v >>= CHAR_BIT;
  59.     }
  60.     }
  61. }
  62.  
  63.  
  64. /* I/O Int Trace */
  65. char *
  66. Struct_TraceInt(cdata, interp,name1,name2,flags)
  67.   ClientData cdata;
  68.   Tcl_Interp *interp;
  69.   char *name1,*name2;
  70.   int flags;
  71. {
  72.     Struct_Object *object = (Struct_Object *)cdata;
  73.     static char res[80];
  74.     int v;
  75.  
  76.  
  77.     if (flags & TCL_TRACE_READS) {
  78.     /* Read an int : */
  79. #ifdef DEBUG
  80.     if (struct_debug & (DBG_INT))
  81.     printf("Struct_TraceInt: Read integer %s\n",
  82.         Struct_ObjectName(object,0) );
  83. #endif
  84.     v = Struct_GetBinaryInt( object->data, object->size, object->type->flags );
  85.     sprintf(res,(object->type->flags & STRUCT_FLAG_UNSIGNED) ? "%u" : "%d", v );
  86. #ifdef DEBUG
  87.     if (struct_debug & (DBG_INT))
  88.     printf(", value = %s\n", res );
  89. #endif
  90.     Tcl_SetVar2(interp,name1,name2,res,flags&TCL_GLOBAL_ONLY);
  91. #ifdef DEBUG
  92.     if (struct_debug & (DBG_INT)) printf("\tv = \"%s\" (stored)\n", res );
  93. #endif
  94.     } else if (flags & TCL_TRACE_WRITES) {
  95.     /* Write an int : */
  96.     char *s;
  97.     int v;
  98. #ifdef DEBUG
  99.     if (struct_debug & (DBG_INT))
  100.     printf("Struct_TraceInt: Writing integer %s\n",
  101.         Struct_ObjectName(object,0) );
  102. #endif
  103.     s = Tcl_GetVar2(interp,name1,name2,flags&TCL_GLOBAL_ONLY);
  104.     if (s == NULL)
  105.         return "null ptr in int write";
  106.     if (Tcl_GetInt(interp,s,&v)==TCL_ERROR) return "not a valid int";
  107.     if (object->type->flags & STRUCT_FLAG_STRICT) {
  108.         if (object->type->flags & STRUCT_FLAG_UNSIGNED) {
  109.         if (*s == '-')
  110.             return "number is negative";
  111.         if ( (object->size < sizeof(int)) &&
  112.              ((unsigned)v >= (1 << (object->size * 8))) )
  113.             return "number too large";
  114.         } else {
  115.         if (object->size < sizeof(int)) {
  116.             if (v >= (int)(1 << (object->size * 8 - 1)))
  117.             return "number too positive";
  118.             else if (v < -(int)(1 << (object->size * 8 - 1)))
  119.             return "number too negative";
  120.         } else if (*s == '-') {
  121.             if (v > 0)
  122.             return "number too negative";
  123.         } else {
  124.              if (v < 0)
  125.             return "number too positive";
  126.         }
  127.         }
  128.         if ( !(object->type->flags & STRUCT_FLAG_NULL_OK) &&
  129.          (v == 0) )
  130.             return "number is zero";
  131.     }
  132.     /* Use memcpy to avoid bus error for misalignment */
  133.     Struct_PutBinaryInt( v, object->data, object->size, object->type->flags );
  134.     } else {
  135.     /* Unset : */
  136. #ifdef DEBUG
  137.     printf("\tunset!\n");
  138. #endif
  139.     Struct_DeleteObject(object);
  140.     }
  141.     return NULL;    
  142. }
  143.  
  144.  
  145. /* I/O Double Trace */
  146. char *
  147. Struct_TraceDouble(cdata, interp,name1,name2,flags)
  148.   ClientData cdata;
  149.   Tcl_Interp *interp;
  150.   char *name1,*name2;
  151.   int flags;
  152. {
  153.   Struct_Object *object = (Struct_Object *)cdata;
  154.   static char res[80];
  155.   double v;
  156.   
  157.   if (flags & TCL_TRACE_READS) {
  158.     /* Read a double : */
  159.     memcpy(&v,object->data,sizeof(v));  /* avoid bus error for misalignment */
  160.     Tcl_PrintDouble(interp,v,res);
  161.     Tcl_SetVar2(interp,name1,name2,res,flags&TCL_GLOBAL_ONLY);
  162.   } else if (flags & TCL_TRACE_WRITES) {
  163.     /* Write a double : */
  164.     char *r;
  165.     r=Tcl_GetVar2(interp,name1,name2,flags&TCL_GLOBAL_ONLY);
  166.     if (r==NULL) return "null ptr in double write";
  167.     if (Tcl_GetDouble(interp,r,&v)==TCL_ERROR) return "not a valid double";
  168.     if (object->type->flags & STRUCT_FLAG_STRICT) {
  169.     if ( (object->type->flags & STRUCT_FLAG_UNSIGNED) &&
  170.          (v < 0.0) )
  171.         return "number is negative";
  172.     if ( !(object->type->flags & STRUCT_FLAG_NULL_OK) &&
  173.          (v == 0.0) )
  174.         return "number is zero";
  175.     }
  176.     memcpy(object->data,&v,sizeof(v));    /* avoid bus error for misalignment */
  177.   } else {
  178.     /* Unset : */
  179. #ifdef DEBUG
  180.     printf("\tunset!\n");
  181. #endif
  182.     Struct_DeleteObject(object);
  183.   }
  184.   return NULL;    
  185. }
  186.  
  187.  
  188. /* I/O Float Trace */
  189. char *
  190. Struct_TraceFloat(cdata, interp,name1,name2,flags)
  191.   ClientData cdata;
  192.   Tcl_Interp *interp;
  193.   char *name1,*name2;
  194.   int flags;
  195. {
  196.   Struct_Object *object = (Struct_Object *)cdata;
  197.   static char res[80];
  198.   float v;
  199.   double d;
  200.   
  201.   if (flags & TCL_TRACE_READS) {
  202.     /* Read a float : */
  203.     memcpy(&v,object->data,sizeof(v));  /* avoid bus error for misalignment */
  204.     d=v;
  205.     Tcl_PrintDouble(interp,d,res);
  206. #ifdef DEBUG
  207.     if (struct_debug & (DBG_FLOAT))
  208.     printf("f=%f,d=%f,r=%s,s=%d\n",v,d,res,sizeof(v));
  209. #endif
  210.     Tcl_SetVar2(interp,name1,name2,res,flags&TCL_GLOBAL_ONLY);
  211.   } else if (flags & TCL_TRACE_WRITES) {
  212.     /* Write a float : */
  213.     char *r;
  214.     r=Tcl_GetVar2(interp,name1,name2,flags&TCL_GLOBAL_ONLY);
  215.     if (r==NULL) return "null ptr in float write";
  216.     if (Tcl_GetDouble(interp,r,&d)==TCL_ERROR) return "not a valid float";
  217.     if (object->type->flags & STRUCT_FLAG_STRICT) {
  218.     if (d > FLT_MAX)
  219.         return "number too positive";
  220.     if (object->type->flags & STRUCT_FLAG_UNSIGNED) {
  221.         if (d < 0.0)
  222.         return "number is negative";
  223.     } else {
  224.         if (d < -FLT_MAX)
  225.         return "number too negative";
  226.     }
  227.     if ( !(object->type->flags & STRUCT_FLAG_NULL_OK) &&
  228.          (d == 0.0) )
  229.         return "number is zero";
  230.     }
  231.     v=d;
  232. #ifdef DEBUG
  233.     if (struct_debug & (DBG_FLOAT))
  234.     printf("f=%f,d=%f,r=%s,s=%d\n",v,d,r,sizeof(v));
  235. #endif
  236.     memcpy(object->data,&v,sizeof(v));    /* avoid bus error for misalignment */
  237.   } else {
  238.     /* Unset : */
  239. #ifdef DEBUG
  240.     printf("\tunset!\n");
  241. #endif
  242.     Struct_DeleteObject(object);
  243.   }
  244.   return NULL;    
  245. }
  246.  
  247.